﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Media;
using TFSTools.TFSLibrary.TestManagement;

namespace TFSTools.TestManagement.TestCaseReview
{
    public class TestActionViewItem : INotifyPropertyChanged
    {
        private TFSTestAction testAction;
        private TestCaseDataContext parent;

        private readonly SolidColorBrush selectedBrush = new SolidColorBrush(Color.FromRgb(255, 240, 200));
        private readonly SolidColorBrush unselectedBrush = new SolidColorBrush(Color.FromRgb(255, 255, 255));

        private bool isSelected;
        private SolidColorBrush itemBackground;

        private bool isParameterNameIncludedInIterationText;

        private string commentHeight;

        private ActionStepText titleStepText1 = new ActionStepText(false);
        private ActionStepText titleParameterStepText1 = new ActionStepText(true);
        private ActionStepText titleStepText2 = new ActionStepText(false);
        private ActionStepText titleParameterStepText2 = new ActionStepText(true);
        private ActionStepText titleStepText3 = new ActionStepText(false);

        private ActionStepText expectedResultStepText1 = new ActionStepText(false);
        private ActionStepText expectedResultParameterStepText1 = new ActionStepText(true);
        private ActionStepText expectedResultStepText2 = new ActionStepText(false);
        private ActionStepText expectedResultParameterStepText2 = new ActionStepText(true);
        private ActionStepText expectedResultStepText3 = new ActionStepText(false);

        public TestActionViewItem(TFSTestAction action, TestCaseDataContext parentViewModel)
        {
            this.testAction = action;
            this.parent = parentViewModel;

            this.isParameterNameIncludedInIterationText = action.TestCase.IncludeParameterNameInIterationText;
            this.IsSelected = false;

            if (string.IsNullOrEmpty(this.testAction.Comment))
            {
                this.CommentHeight = "0";
            }
            else
            {
                this.CommentHeight = "auto";
            }
        }

        public bool IsSelected 
        {
            get 
            { 
                return this.isSelected; 
            }

            set
            {
                this.isSelected = value;

                if (this.isSelected)
                {
                    this.itemBackground = this.selectedBrush;
                }
                else
                {
                    this.itemBackground = this.unselectedBrush;
                }

                this.OnPropertyChanged("IsSelected");
                this.OnPropertyChanged("ItemBackground");
            }
        }

        public ActionStepText Title1 { get { return this.titleStepText1; } }

        public ActionStepText TitleParameter1 { get { return this.titleParameterStepText1; } }

        public ActionStepText Title2 { get { return this.titleStepText2; } }

        public ActionStepText TitleParameter2 { get { return this.titleParameterStepText2; } }

        public ActionStepText Title3 { get { return this.titleStepText3; } }

        public ActionStepText ExpectedResult1 { get { return this.expectedResultStepText1; } }

        public ActionStepText ExpectedResultParameter1 { get { return this.expectedResultParameterStepText1; } }

        public ActionStepText ExpectedResult2 { get { return this.expectedResultStepText2; } }

        public ActionStepText ExpectedResultParameter2 { get { return this.expectedResultParameterStepText2; } }

        public ActionStepText ExpectedResult3 { get { return this.expectedResultStepText3; } }

        public void IterationUpdated()
        {
            char[] separator = { this.testAction.ParameterDelimiter };

            this.isParameterNameIncludedInIterationText = this.testAction.TestCase.IncludeParameterNameInIterationText;

            if (!string.IsNullOrEmpty(this.testAction.Title))
            {
                var splitSource = this.testAction.Title.Split(separator);

                this.SetStepText(splitSource, 0, this.titleStepText1);
                this.SetStepText(splitSource, 1, this.titleParameterStepText1);
                this.SetStepText(splitSource, 2, this.titleStepText2);
                this.SetStepText(splitSource, 3, this.titleParameterStepText2);
                this.SetFinalStepText(splitSource, 4, this.titleStepText3);

                this.OnPropertyChanged("Title");
                this.OnPropertyChanged("Title1");
                this.OnPropertyChanged("TitleParameter1");
                this.OnPropertyChanged("Title2");
                this.OnPropertyChanged("TitleParameter2");
                this.OnPropertyChanged("Title3");
            }

            if (!string.IsNullOrEmpty(this.testAction.ExpectedResult))
            {
                var splitSource = this.testAction.ExpectedResult.Split(separator);
                this.SetStepText(splitSource, 0, this.expectedResultStepText1);
                this.SetStepText(splitSource, 1, this.expectedResultParameterStepText1);
                this.SetStepText(splitSource, 2, this.expectedResultStepText2);
                this.SetStepText(splitSource, 3, this.expectedResultParameterStepText2);
                this.SetFinalStepText(splitSource, 4, this.expectedResultStepText3);

                this.OnPropertyChanged("ExpectedResult");

                this.OnPropertyChanged("ExpectedResult1");
                this.OnPropertyChanged("ExpectedResultParameter1");
                this.OnPropertyChanged("ExpectedResult2");
                this.OnPropertyChanged("ExpectedResultParameter2");
                this.OnPropertyChanged("ExpectedResult3");
            }
        }

        private void SetStepText(string[] source, int index, ActionStepText actionStepText)
        {
            if (source.Length > index)
            {
                actionStepText.Text = source[index].Trim();
            }
            else
            {
                actionStepText.Text = string.Empty;
            }
        }

        private void SetFinalStepText(string[] source, int index, ActionStepText actionStepText)
        {
            if (source.Length > index)
            {
                StringBuilder finalText = new StringBuilder();

                for (int sourceIndex = index; source.Length > sourceIndex; sourceIndex++)
                {
                    finalText.Append(source[sourceIndex].Trim());
                    finalText.Append(" ");
                }

                actionStepText.Text = finalText.ToString();
            }
            else
            {
                actionStepText.Text = string.Empty;
            }
        }

        public decimal StepNumber { get { return this.testAction.StepNumber; } }

        public int StepNumberColumnWidth 
        { 
            get 
            {
                if (this.testAction.ActionType == TFSTestActionType.SharedStep)
                {
                    return 45;
                }
                else
                {
                    return 30; 
                }
            } 
        }

        public string Title { get { return this.testAction.Title; } }

        public string ExpectedResult { get { return this.testAction.ExpectedResult; } }

        public string CommentHeight 
        {
            get { return this.commentHeight; }
            set
            {
                this.commentHeight = value;
                this.OnPropertyChanged("CommentHeight");
            }
        }

        public string Comment 
        {
            get { return this.testAction.Comment; }
            set
            {
                if (this.testAction.Comment != value)
                {
                    this.testAction.Comment = value;
                    this.parent.IsCommentsDirty = true;
                }
            }
        }

        public bool HasExpectedResult
        {
            get { return !string.IsNullOrEmpty(this.ExpectedResult); }
        }

        public Brush ItemBackground
        {
            get
            {
                return this.itemBackground;
            }
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class TestActionViewItemCollection : List<TestActionViewItem>
    {
        public TestActionViewItemCollection(TFSTestActionCollection list, TestCaseDataContext parent)
        {
            foreach (var item in list)
            {
                this.Add(new TestActionViewItem(item, parent));
            }

            this.IterationUpdated();
        }

        internal void IterationUpdated()
        {
            this.ForEach(x => x.IterationUpdated());
        }

        public void ShowCommentsOnSelectedItems()
        {
            foreach (var items in this)
            {
                if (items.IsSelected)
                {
                    items.CommentHeight = "auto";
                }
            }
        }

        public void ClearAllComments()
        {
            foreach (var items in this)
            {
                items.Comment = string.Empty;
                items.CommentHeight = "0";
            }
        }
    }

    public class ActionStepText
    {
        public ActionStepText(bool isParameter)
        {
            if (isParameter)
            {
                this.ItemBackground = new SolidColorBrush(Colors.LightGreen);
            }
        }

        public string Text { get; set; }

        public Brush ItemBackground { get; set; }

        public override string ToString()
        {
            return this.Text;
        }
    }
}
